/**
 * Copyright 2006 gworks.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 */
package org.javaongems.client.stdctrls;

import java.util.ArrayList;
import java.util.Iterator;

import org.javaongems.client.rt.text.dom.DomExtUtils;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.ClickListenerCollection;
import com.google.gwt.user.client.ui.MouseListener;
import com.google.gwt.user.client.ui.MouseListenerCollection;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;

/**
 * <p>Provides a panel is based on the Swing border layout. Indeed this is
 * very similar to DockPanel, but is design to be more restrictive.</p>
 * @author Ashin Wimalajeewa (ash)
 */
public class BorderLayoutPanel extends Panel {
	final static public int	CENTER = 0;
	final static public int	NORTH = 1;
	final static public int	SOUTH = 2;
	final static public int	EAST = 3;
	final static public int	WEST = 4;
	
	protected Widget[]	borders = new Widget[5];
	protected Element	container;
	protected Element	table;
	protected Element 	tbody;
	protected Element[]	tdBorders = new Element[5];
	protected Element 	trNorth, trMiddle, trSouth;
	
	protected ClickListenerCollection clickListeners;
	protected MouseListenerCollection mouseListeners;
	
	public BorderLayoutPanel() {
		container = DOM.createDiv();
		setElement(container);
		sinkEvents(Event.ONCLICK | Event.MOUSEEVENTS);
		buildTable();
	}
	
	public void setWidget(Widget w, int direction) {
		if (borders[direction] != w) {
			if (borders[direction] != null) {
				Element elm = borders[direction].getElement();
				DOM.removeChild(tdBorders[direction], elm);
				disown(borders[direction]);
			}
			if (w != null) {
// 1.0.21				
//				DOM.appendChild(tdBorders[direction], w.getElement());
//				adopt(w);
				adopt(w, tdBorders[direction]);
			}
			borders[direction] = w;
			UIObject.setVisible(tdBorders[direction], w != null);
			if (direction == NORTH || direction == SOUTH)
				prepareNorthSouthContainer(direction, w != null);
		}
	}
	
	private void prepareNorthSouthContainer(int direction, boolean show) {
		Element parent = DOM.getParent(tdBorders[direction]);
		UIObject.setVisible(parent, show);
		Element prntParent = DOM.getParent(parent);
		if (show) {
			if (prntParent == null) {
				if (direction == NORTH) 
					DOM.insertChild(tbody, parent, 0);
				else
					DOM.appendChild(tbody, parent);
			}
		} else {
			if (prntParent != null)
				DOM.removeChild(tbody, parent);
		}
	}
	
	public void add(Widget w) {
	}

	public void clear() {
		removeFromDom();
		removeAssociations();
	}

	private void removeFromDom() {
		for (int i = 0; i < borders.length; i++) {
			if (borders[i] != null) {
				Element e = borders[i].getElement();
				Element p = tdBorders[i];
				DOM.removeChild(p, e);
			}
		}		
	}
	
	private void removeAssociations() {
		for (int i = 0; i < borders.length; i++) {
			if (borders[i] != null)
				disown(borders[i]);
		}
	}

	public boolean remove(Widget w) {
		return false;
	}

	public Iterator iterator() {
		ArrayList tmp = new ArrayList();
		for (int i = 0; i < borders.length; i++) {
			if (borders[i] != null) 
				tmp.add(borders[i]);
		}
		return tmp.iterator();
	}
	
	private void buildTable() {
		Element td = null;
		table = DomExtUtils.createAndAppendElement(container, "table");
		DOM.setStyleAttribute(table, "width", "100%");
		DOM.setStyleAttribute(table, "height", "100%");
		tbody = DomExtUtils.createAndAppendElement(table, "tbody");
		
		trNorth = DOM.createElement("tr");	// not attached
		DOM.setStyleAttribute(trNorth, "vertical-align", "top");
		UIObject.setVisible(trNorth, false);
		td = DomExtUtils.createAndAppendElement(trNorth, "td");
		UIObject.setVisible(td, false);
		tdBorders[NORTH] = DomExtUtils.createAndAppendElement(trNorth, "td");
		UIObject.setVisible(tdBorders[NORTH], false);
		td = DomExtUtils.createAndAppendElement(trNorth, "td");
		UIObject.setVisible(td, false);
//		DOM.setIntAttribute(tdBorders[NORTH], "colspan", 3);
		
		trMiddle = DomExtUtils.createAndAppendElement(tbody, "tr");
		DOM.setStyleAttribute(trMiddle, "vertical-align", "top");
		tdBorders[WEST] = DomExtUtils.createAndAppendElement(trMiddle, "td");
		UIObject.setVisible(tdBorders[WEST], false);
		tdBorders[CENTER] = DomExtUtils.createAndAppendElement(trMiddle, "td");
		UIObject.setVisible(tdBorders[CENTER], false);
		DOM.setAttribute(tdBorders[CENTER], "width", "100%");
		tdBorders[EAST] = DomExtUtils.createAndAppendElement(trMiddle, "td");
		UIObject.setVisible(tdBorders[EAST], false);
		
		trSouth = DOM.createElement("tr");	// not attached
		DOM.setStyleAttribute(trSouth, "vertical-align", "bottom");
		UIObject.setVisible(trSouth, false);
		td = DomExtUtils.createAndAppendElement(trSouth, "td");
		UIObject.setVisible(td, false);
		tdBorders[SOUTH] = DomExtUtils.createAndAppendElement(trSouth, "td");
		UIObject.setVisible(tdBorders[SOUTH], false);
		td = DomExtUtils.createAndAppendElement(trSouth, "td");
		UIObject.setVisible(td, false);
//		DOM.setIntAttribute(tdBorders[SOUTH], "colspan", 3);
	}
	
	public void addClickListener(ClickListener listener) {
		if (clickListeners == null)
			clickListeners = new ClickListenerCollection();
		clickListeners.add(listener);
	}

	public void addMouseListener(MouseListener listener) {
		if (mouseListeners == null)
			mouseListeners = new MouseListenerCollection();
		mouseListeners.add(listener);
	}

	public void removeClickListener(ClickListener listener) {
		if (clickListeners != null)
			clickListeners.remove(listener);
	}

	public void removeMouseListener(MouseListener listener) {
		if (mouseListeners != null)
			mouseListeners.remove(listener);
	}

	public void onBrowserEvent(Event event) {
		switch (DOM.eventGetType(event)) {
		case Event.ONCLICK:
			if (clickListeners != null)
				clickListeners.fireClick(this);
			break;

		case Event.ONMOUSEDOWN:
		case Event.ONMOUSEUP:
		case Event.ONMOUSEMOVE:
		case Event.ONMOUSEOVER:
		case Event.ONMOUSEOUT:
			if (mouseListeners != null)
				mouseListeners.fireMouseEvent(this, event);
			break;
		}
	}
}